home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
4_0
/
STANDALO
/
COMMENTF
/
COMMENT.C
< prev
Wrap
Text File
|
1990-04-22
|
14KB
|
557 lines
/*----------------------------------------------------------------------------+
| |
| comment.c |
| |
| This is code for an FKEY to do various commenting functions for C code. |
| It takes text on the clipboard (or on the TEScrap), operates on it, |
| and replaces it. |
| |
| If the option key is pressed within KEYDELAY ticks after the FKEY is |
| called, the clipboard text will be commented with a line running down |
| the left side, and the text indented with tabs. |
| |
| If the tab key is pressed within KEYDELAY ticks, the text will be |
| surrounded with / * and * / characters, and any previously commented |
| text will be replaced with SLASHREPLACEMENT (since commented comments |
| aren't allowed in C). |
| |
| If the accent ("`") key is pressed with KEYDELAY ticks, the text |
| will be assumed to have been previously commented, and any surrounding |
| comment marks will be removed and any temporarily uncommented lines |
| will be commented back in. It is the inverse of the previous |
| operation. |
| |
| If no key is pressed within KEYDELAY ticks, the text will be surrounded |
| in a large box, like this one. |
| |
| This FKEY does not (yet) work with programs that keep a private |
| scrap (such as Word). How can I easily trick those programs into |
| putting their scrap on the clipboard? |
| |
| This code and FKEY is free, but may not be resold and is copyrighted |
| 1990 by David S. Fry. |
| |
| David Fry |
| 81 Irving Street |
| Cambridge, MA 02138 |
| INTERNET: fry@math.harvard.edu |
| April 22, 1990 |
| |
+----------------------------------------------------------------------------*/
/* my own version of isspace() */
#define isspace(x) (( (x) <= ' ' ) ? TRUE : FALSE)
#define TABSPACE 4 /* spaces for tab in editor */
#define LEFTCHAR '|' /* left char on box */
#define RIGHTCHAR '|' /* right char on box */
#define LINELEN 78 /* length of line */
#define TOPCHAR '-' /* top of box */
#define BOTCHAR '-' /* bottom of box */
#define CORNERCHAR '+' /* corner of box */
#define SIDECHAR '*' /* left side char */
#define SLASHREPLACEMENT '|' /* what to replace "/" with */
#define NULL 0L
/* how many ticks to wait for user to press option, tab, or accent */
#define KEYDELAY 45
/* key codes */
#define option_kc 58
#define tab_kc 48
#define accent_kc 50
/*----------------------------------------------------------------------------+
| Add text from little buffer to the big output buffer. |
+----------------------------------------------------------------------------*/
Ptr AddToOutText(textBuf,addBuf,len)
Ptr textBuf,addBuf;
long len;
/*
* This function takes text from the temporary buffer addBuff and
* adds it to the text buffer textBuf.
*
* If there's a problem, it kills textBuf and returns NULL.
*/
{
long outSize;
Ptr temp;
outSize = GetPtrSize(textBuf);
SetPtrSize(textBuf,outSize+len);
if ( MemError() != noErr ) {
/* hit a nonreloc block */
temp = NewPtr((long)(outSize+len));
if ( temp == NULL ) {
DisposPtr(textBuf);
return(NULL);
}
BlockMove(textBuf,temp,outSize);
DisposPtr(textBuf);
textBuf = temp;
}
BlockMove(addBuf,textBuf+outSize,len);
return(textBuf);
}
/*----------------------------------------------------------------------------+
| Check for key presses. |
+----------------------------------------------------------------------------*/
Boolean CheckKeyCode(kc)
char kc;
/*
* Checks to see if the key with kc key code is down
*/
{
KeyMap theKeys;
GetKeys(&theKeys);
return( BitTst(&theKeys,
(long) ((kc/8)*8 + 7 - (kc%8) ) ));
}
/*----------------------------------------------------------------------------+
| Comment out (and in) large sections. |
| Called if the tab key or "`" key is pressed. |
+----------------------------------------------------------------------------*/
Ptr CommentOut(inH,inSize,addcmts)
Handle inH;
long inSize;
Boolean addcmts;
/*
* returns pointer to text
*/
{
long y;
char *inT, *endT;
char *outT;
char buf[10];
long beginning, ending;
char *temp;
inT = *inH;
endT = inT + inSize;
outT = NewPtr(0L);
if ( addcmts ) {
/*
* We will comment out the whole section, and replace
* any existing comments.
*/
y = 0;
buf[y++] = '/';
buf[y++] = '*';
buf[y++] = '\r';
outT = AddToOutText(outT,buf,y);
if ( outT == NULL )
return(NULL);
while ( inT < endT ) {
if ( *inT == '/' &&
(*(inT + 1) == '*' || *(inT-1) == '*') )
*inT = SLASHREPLACEMENT;
inT++;
}
inT = *inH;
outT = AddToOutText(outT,inT,inSize);
if ( outT == NULL )
return(NULL);
y = 0;
buf[y++] = '*';
buf[y++] = '/';
buf[y++] = '\r';
outT = AddToOutText(outT,buf,y);
} else {
/*
* We will remove any surrounding comments (ignoring
* text outside the first level of commenting) and
* fix any previously replaced comments.
*/
while ( inT < endT &&
!(*inT == '/' && *(inT+1) == '*') ) {
inT++;
}
if ( inT < endT )
inT += 2;
if ( inT < endT && *inT == '\r' )
inT++;
beginning = inT - *inH;
if ( beginning == inSize )
beginning = 0;
inT = endT-1;
temp = *inH + beginning;
while ( inT > temp &&
!(*inT == '*' && *(inT+1) == '/') ) {
inT--;
}
ending = endT - inT;
if ( ending == inSize )
ending = 0;
inT = *inH + beginning;
endT = *inH + inSize - ending;
while ( inT < endT ) {
if ( *inT == SLASHREPLACEMENT &&
( *(inT+1) == '*' || *(inT-1) == '*') )
*inT = '/';
inT++;
}
inT = *inH + beginning;
outT = AddToOutText(outT,inT,inSize - beginning - ending);
}
return(outT);
}
/*----------------------------------------------------------------------------+
| Add comments on the left side of text. |
| Called when the option key is pressed. |
+----------------------------------------------------------------------------*/
Ptr SideNote(inH,inSize)
Handle inH;
long inSize;
/*
* returns pointer to text
*/
{
long y;
char *inT, *endT;
char *outT;
char buf[256];
char firstpart[50];
long firstlen;
long actualcnt;
long firstactual;
inT = *inH;
endT = inT + inSize;
firstlen = 0; firstactual = 0;
while ( inT < endT ) {
if ( *inT == '\r' ) {
/* end of line...start over */
*inT++;
firstlen = 0;
firstactual = 0;
continue;
}
if ( isspace(*inT) ) {
firstpart[firstlen] = *inT;
firstlen++;
inT++;
if ( *inT == '\t' )
firstactual = ((firstactual + TABSPACE)/TABSPACE)*TABSPACE;
else
firstactual++;
} else
/* we've run out of white space */
break;
}
inT = *inH;
outT = NewPtr(0L);
/* now we put in the first line */
y = 0;
while ( y < firstlen ) {
buf[y] = firstpart[y];
y++;
}
buf[y++] = '/';
buf[y++] = '*';
buf[y++] = '\r';
outT = AddToOutText(outT,buf,y);
if ( outT == NULL )
return(NULL);
do {
/*
* First we need to remove the beginning part of the the line
* so everything lines up properly.
*/
actualcnt = 0;
while ( actualcnt < firstactual
&& inT < endT && *inT != '\r' ) {
if ( *inT == '\t' )
actualcnt = ((actualcnt+TABSPACE)/TABSPACE)*TABSPACE;
else
actualcnt++;
inT++;
}
if ( *inT == '/' && *(inT+1) == '*' ) {
/* skip this line */
while ( inT < endT && *inT != '\r' ) { inT++; }
if ( inT < endT )
inT++;
continue;
}
if ( (*inT == '*' && *(inT+1) == '/') ||
(*inT == '/' && *(inT-1) == '*') ) {
/* skip this line */
while ( inT < endT && *inT != '\r' ) { inT++; }
if ( inT < endT )
inT++;
continue;
}
if ( *inT == SIDECHAR ) {
inT++;
if ( *inT == '\t' )
inT++;
}
y = 0;
while ( y < firstlen ) {
buf[y] = firstpart[y];
y++;
}
buf[y++] = SIDECHAR;
buf[y++] = '\t';
while ( inT < endT && *inT != '\r' ) {
buf[y++] = *inT;
inT++;
}
if ( *inT == '\r' ) {
buf[y++] = '\r';
inT++;
}
outT = AddToOutText(outT,buf,(long)y);
if ( outT == NULL )
return(NULL);
} while ( inT < endT );
/* now put in last line */
y = 0;
while ( y < firstlen ) {
buf[y] = firstpart[y];
y++;
}
buf[y++] = '*';
buf[y++] = '/';
buf[y++] = '\r';
outT = AddToOutText(outT,buf,(long)y);
return(outT);
}
/*----------------------------------------------------------------------------+
| Surround the text with a big box like this. |
| Called when no key is presed for KEYDELAY Ticks. |
+----------------------------------------------------------------------------*/
Ptr BigBox(inH,inSize)
Handle inH;
long inSize;
/*
* returns pointer to text
*/
{
long x,y;
char *inT, *endT;
char *outT;
char buf[256];
Boolean firstChar;
short actualcnt;
inT = *inH;
endT = inT + inSize;
outT = NewPtr(0L);
/* put in first line */
y = 0;
buf[y++] = '/';
buf[y++] = '*';
for ( x = 0; x < LINELEN - 2; x++ )
buf[y++] = TOPCHAR;
buf[y++] = CORNERCHAR;
buf[y++] = '\r';
outT = AddToOutText(outT,buf,(long)y);
if ( outT == NULL )
return(NULL);
inT = *inH;
do {
if ( *inT == '/' && *(inT+1) == '*' && *(inT+2) == TOPCHAR ) {
/* skip this line */
while ( inT < endT && *inT != '\r' ) { inT++; }
if ( inT < endT )
inT++;
continue;
}
if ( *inT == CORNERCHAR && *(inT+1) == BOTCHAR && *(inT+2) == BOTCHAR ) {
/* skip this line */
while ( inT < endT && *inT != '\r' ) { inT++; }
if ( inT < endT )
inT++;
continue;
}
firstChar = TRUE;
y = 0;
actualcnt = 0;
buf[y++] = LEFTCHAR;
actualcnt++;
while ( inT < endT && *inT != '\r' ) {
if ( firstChar ) {
firstChar = FALSE;
if ( *inT == LEFTCHAR ) {
inT++;
continue;
}
}
buf[y++] = *inT;
if ( *inT == '\t' )
/* tab */
actualcnt = ((actualcnt+TABSPACE)/TABSPACE)*TABSPACE;
else
actualcnt++;
inT++;
}
if ( *inT == '\r' ) {
if ( *(inT-1) != RIGHTCHAR || y < 2 ) {
/* pad with spaces */
while ( actualcnt < LINELEN ) {
buf[y++] = ' ';
actualcnt++;
}
buf[y++] = RIGHTCHAR;
}
buf[y++] = '\r';
inT++;
}
outT = AddToOutText(outT,buf,(long)y);
if ( outT == NULL )
return(NULL);
} while ( inT < endT );
/* now put bottom line */
y = 0;
buf[y++] = CORNERCHAR;
for ( x = 0; x < LINELEN - 2; x++ )
buf[y++] = BOTCHAR;
buf[y++] = '*';
buf[y++] = '/';
buf[y++] = '\r';
outT = AddToOutText(outT,buf,(long)y);
return(outT);
}
/*----------------------------------------------------------------------------+
| Main function. |
+----------------------------------------------------------------------------*/
main()
{
Handle inH;
long inSize;
long offset;
Boolean useTEScrap = FALSE;
long time;
Boolean opt = FALSE, tab = FALSE, accent = FALSE;
Ptr outT;
time = TickCount();
do {
opt = CheckKeyCode(option_kc);
tab = CheckKeyCode(tab_kc);
accent = CheckKeyCode(accent_kc);
} while ( TickCount() - time < KEYDELAY &&
!(opt || tab || accent) );
if ( opt || tab || accent )
FlushEvents(keyDownMask+keyUpMask+autoKeyMask,0);
if ( TEGetScrapLen() > 0 ) {
useTEScrap = TRUE;
ZeroScrap();
TEToScrap();
}
inH = NewHandle(0L);
inSize = GetScrap(inH,'TEXT',&offset);
if ( inSize < 0 ) {
/* no text there */
DisposHandle(inH);
SysBeep(30);
return;
}
MoveHHi(inH);
HLock(inH);
if ( opt )
outT = SideNote(inH,inSize);
else if ( tab )
outT = CommentOut(inH,inSize,TRUE);
else if ( accent )
outT = CommentOut(inH,inSize,FALSE);
else
outT = BigBox(inH,inSize);
HUnlock(inH);
DisposHandle(inH);
if ( outT == NULL ) {
SysBeep(30);
return;
}
ZeroScrap();
PutScrap(GetPtrSize(outT),'TEXT',outT);
if ( useTEScrap )
TEFromScrap();
DisposPtr(outT);
return;
}